﻿package jojo.bitmapRenderer {
	import flash.display.Sprite;
	import flash.display.BitmapData;
	import flash.display.Bitmap;
	import flash.events.Event;
	import flash.geom.Rectangle;
	import flash.geom.Point;
	import flash.display.MovieClip;

	/**
	 * ...
	 * @author jo
	 * 
	 * для програвання анімації за допомогою BitmapData
	 */
	public class SpriteAnim extends Sprite {
		private var animCopyArray : Array;
		private var animLabelsArray : Array;
		private var spriteBitmap : Bitmap;
		private var rect : Rectangle;
		private var pt : Point;

		private var loop : Boolean;

		private var frameCounter : int = 0;
		private var maxFrames : int = 0;

		public function SpriteAnim(copyArray : Array, loop : Boolean = true, x : int = 0, y : int = 0) {
			this.animCopyArray = copyArray["animation"];
			this.animLabelsArray = copyArray["labels"];
			
			this.loop = loop;
			this.x = x;
			this.y = y;
				
			render();
		}

		public function stop() : void {
			stopAnim();
		}

		public function play() : void {
			playAnim();
		}

		public function gotoAndPlay(frame : Object) : void {
			playAnim(frame);
		}

		public function gotoAndStop(frame : Object) : void {
			stopAnim(frame);
		}

		
		private function playAnim(frame : Object = null) : void {
			if(!this.hasEventListener(Event.ENTER_FRAME)) {
				this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
			}
			
			if(frame) {
				frameCounter = frameValidator(frame);
			}
		}

		private function stopAnim(frame : Object = null) : void {
			if(this.hasEventListener(Event.ENTER_FRAME)) {
				this.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
			}
			
			if(frame) {
				frameCounter = frameValidator(frame);
				
				spriteBitmap.bitmapData.copyPixels(animCopyArray[frameCounter], rect, pt);
				frameCounter++;
			}
		}

		private function frameValidator(frame : Object) : uint {
			if(frame is String) {
				var labelFrameNum : int = animLabelsArray.indexOf(String(frame));
				if(labelFrameNum != -1) {
					return labelFrameNum;
				}
				else {
					trace("label not found");
				}
			}
			else if(frame is uint) {
				var goToFrame : uint = uint(frame);
				if(frame > (maxFrames - 1)) {
					goToFrame = 0;
				}
				return goToFrame;
			}
			return 0;
		}

		/*
		 * Промальовка анымації
		 */
		private function render() : void {
			
			maxFrames = animCopyArray.length + 1;
			rect = new Rectangle(0, 0, animCopyArray[0].width, animCopyArray[0].height);
			pt = new Point(0, 0);
			
			var myBitmapData : BitmapData = new BitmapData(animCopyArray[0].width, animCopyArray[0].height, true, 0);
			spriteBitmap = new Bitmap(myBitmapData);
			this.addChild(spriteBitmap);
			
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}

		/*
		 * Програє анімацію
		 */
		private function onEnterFrame(e : Event = null) : void {						
			if(loop == false && frameCounter == (maxFrames - 2)) {
				this.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
			}
			
			if (frameCounter == (maxFrames - 1)) {
				frameCounter = 0;
			}
			spriteBitmap.bitmapData.copyPixels(animCopyArray[frameCounter], rect, pt);
			frameCounter++;
		}

		/*
		 * функція яка копіює анімацію з мувікліпу
		 */
		public static function copyAnimation(mc : MovieClip) : Array {
			var maxFrames : int = mc.totalFrames;
			var animCopy : Array = new Array;
			var animLabels : Array = new Array;
		
			for (var i : Number = 1;i <= maxFrames; i++) { 
				var mcBitmapData : BitmapData = new BitmapData(mc.width, mc.height, true, 0);
				mc.gotoAndStop(i);
				animLabels.push(mc.currentLabel);
				mcBitmapData.draw(mc);
				animCopy.push(mcBitmapData);
			} 
			mc = undefined;
			
			var copyArray : Array = new Array;
			copyArray["animation"] = animCopy;
			copyArray["labels"] = animLabels;
			
			return copyArray;
		}
	}
}